﻿using IPC.DbMapper;
using IPC.LogCommon.DelegateAndEvent;
using IPC.MongoDB;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace IPC.ListConnect.Profinet.TagThread
{
    public static class TagThreadPool
    {
        private static Dictionary<string,TagTimer> timers = new Dictionary<string,TagTimer>();

        #region 添加标签
        /// <summary>
        /// 添加标签
        /// </summary>
        /// <param name="tag"></param>
        /// <returns></returns>
        public static string AddTag(Tag tag)
        {
            try
            {
                bool b = false;
                foreach (var timer in timers.ToArray())
                {
                    if (timer.Value.Count < 200)
                    {
                        b = timer.Value.Add(tag);
                        if (b)
                        {
                            break;
                        }
                    }
                }
                if (!b)
                {
                    string guid = AddTimer(tag);
                    timers[guid].Add(tag);
                    if (!timers[guid].IsRunning)
                    {
                        timers[guid].Start();
                    }
                }
                return "OK";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private static string AddTimer(Tag tag)
        {
            bool b = false;
            if (timers.Count > 20)
            {
                foreach (var timer in timers.ToArray())
                {
                    if (timer.Value.Frequency == tag.Frequency)
                    {
                        b = true;
                        return timer.Value.ToString();
                    }
                }
            }
            else
            {
                string guid2 = Guid.NewGuid().ToString();
                timers.Add(guid2, new TagTimer());
                return guid2;
            }

            string guid = Guid.NewGuid().ToString();
            timers.Add(guid, new TagTimer());
            return guid;
        }
        #endregion

        #region 移除标签
        /// <summary>
        /// 移除标签
        /// </summary>
        /// <param name="tag"></param>
        public static void RemoveTag(Tag tag)
        {
            foreach (var item in timers.ToArray())
            {
                bool b = item.Value.Remove(tag);
                if (b)
                {
                    if (item.Value.Count <= 0)
                    {
                        item.Value.Stop();
                        timers.Remove(item.Key);
                    }
                    break;
                }
            }
        }
        #endregion
    }

    /// <summary>
    /// 初始化标签刷新容器
    /// </summary>
    public class TagTimer: System.Timers.Timer
    {
        private List<Tag> tags;

        /// <summary>
        /// 准备一个点位容器
        /// </summary>
        public TagTimer() {
            tags = new List<Tag>();
            this.Elapsed += TagTimer_Elapsed;
        }

        private void TagTimer_Elapsed(object? sender, ElapsedEventArgs e)
        {
            try
            {
                this.Enabled = false;
                if (tags.Count > 0)
                {
                    foreach (Tag tag in tags.ToArray())
                    {
                        if (tag.DataType == DataType.UInt16 || tag.DataType == DataType.UInt32 || tag.DataType == DataType.UInt64 || tag.DataType == DataType.Int16 || tag.DataType == DataType.Int32 || tag.DataType == DataType.Int64 ||
                        tag.DataType == DataType.Float || tag.DataType == DataType.Double)
                        {
                            if (tag.IsSuccess)
                            {
                                tag.Value = (tag.RealValue.ToDouble(0) * tag.Zoom).ToString();
                                MongoOperate.Instance.Insert(tag.FullName, DateTime.Now.ToString(), tag.Value.ToDouble(-99));
                                DelegateAndEvent.Instance.RefreshSeries(tag.FullName, DateTime.Now.ToString(), tag.Value);
                            }
                            else
                            {
                                tag.Value = "未知";
                            }
                        }
                        else if(tag.DataType == DataType.Bool)
                        {
                            if (tag.IsSuccess)
                            {
                                tag.Value = tag.RealValue;
                                bool b = tag.Value.ToBool(true);
                                if (b)
                                {
                                    MongoOperate.Instance.Insert(tag.FullName, DateTime.Now.ToString(), 1);
                                    DelegateAndEvent.Instance.RefreshSeries(tag.FullName, DateTime.Now.ToString(), tag.Value);
                                }
                                else
                                {
                                    MongoOperate.Instance.Insert(tag.FullName, DateTime.Now.ToString(), 0);
                                    DelegateAndEvent.Instance.RefreshSeries(tag.FullName, DateTime.Now.ToString(), tag.Value);
                                }
                            }
                            else
                            {
                                tag.Value = "未知";
                            }
                        }
                        else
                        {
                            if (tag.IsSuccess)
                            {
                                tag.Value = tag.RealValue;
                            }
                            else
                            {
                                tag.Value = "未知";
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                
            }
            finally {
                this.Enabled = true;
            }
        }

        public int Frequency = 0;//扫描频率

        public int Count = 0; //已存储的标签数量

        public bool IsRunning = false;
        public bool Add(Tag tag)
        {

            if (tags.Where(o => o.FullName == tag.FullName).Count()>0)
                return true;

            if(tags.Count == 0)
            {
                Frequency = tag.Frequency;
                if (Frequency <= 0)
                {
                    this.Interval = 1000;
                }
                else
                {
                    this.Interval = Frequency;
                }
            }
            if(tag.Frequency == this.Frequency)
            {
                tags.Add(tag);
                Count++;
                return true;
            }
            return false;
        }

        public bool Remove(Tag tag)
        {
            foreach (Tag tag2 in tags.ToArray()) {
                if(tag2.FullName == tag.FullName)
                {
                    tags.Remove(tag2);
                    Count--;
                    return true;
                }
            }
            return false;
        }

        public void Start()
        {
            base.Start();
            this.IsRunning = true;
        }

        public void Stop()
        {
            base.Stop();
            this.IsRunning = false;
        }
    }
}
